#pragma once
#include<cstdio>
#include<pthread.h>
#include<assert.h>
#include<string>
#include<functional>


class mock_thread
{
public:
    typedef std::function<void *(void *)> _start_run;

    mock_thread()
    {}

    void start(_start_run fun, void *args = nullptr)
    {
        _fun = fun;
        _args = args;
        pthread_create(&_id, NULL, start_routine, this);
    }

    void join()
    {
        pthread_join(_id, nullptr);
    }

    static void *start_routine(void *args)
    {
        mock_thread *_this = (mock_thread *)args;
        _this->_fun(_this->_args);
    }

    ~mock_thread() {}

private:
    pthread_t _id;
    _start_run _fun;
    void *_args;
};



// class mock_thread;

// class Change
// {
// public:
//     mock_thread* _this = nullptr;
//     void* _args = nullptr;
// };

// class mock_thread
// {
// public:

// //包装线程执行函数
// typedef std::function<void*(void*)> _start_run;

//     mock_thread(_start_run fun, void* args = nullptr, int number = 0)
//     :_fun(fun), _args(args)
//     {
//         char buff[64] = {0};
//         snprintf(buff, sizeof buff, "%d号线程", number);
//         _name = buff;
//     }
    
//     void start()
//     {
        
//         //C语言并不支持C++包装器包装的函数
//         //pthread_create(&_id, NULL, _fun(), _args);
        
//         //因为start_routine是类内成员函数，缺省了参数 this指针故而加上static
//         //pthread_create(&_id, NULL, start_routine, _args);
        
//         Change* cg = new Change; 
//         assert(cg != nullptr);
//         cg->_this = this;
//         cg->_args = this->_args;

//         pthread_create(&_id, NULL, start_routine, cg);

//     }

//     void join()
//     {
//         void* re_val;
//         pthread_join(_id, &re_val);
//     }

//     ~mock_thread(){}

// private:

//     void* run(void* arg)
//     {
//         this->_fun(arg);
//     }

//     static void* start_routine(void* args)
//     {
//         //static函数只能调用static方法和成员变量
//         //return _fun(_args);

//         Change* cg = static_cast<Change*>(args);
//         void* ret = cg->_this->run(cg->_args);
//         delete cg;
//         return ret;     
//     }

// private:
//     pthread_t _id;
//     std::string _name;
//     _start_run _fun;
//     void* _args;
// };

